home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Over 1,000 Windows 95 Programs
/
Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso
/
1258
/
easyjava.exe
/
SAMPLES
/
TRACK.JAV
< prev
Wrap
Text File
|
1996-03-09
|
11KB
|
492 lines
// Track.java
/*
* Copyright (c) 1996 by Corey Trager.
*
* Permission to use, copy, and distribute this software for
* any purpose and without fee is hereby granted provided
* that this copyright notice appears in all copies.
*
*/
// Track is the abstract class
// StraightTrack, CurvedTrack, and SwitchTrack are
// all derived from Track.
// The Track class and the TrackCollection class
// collaborate
import java.lang.Math;
// import java.awt.*;
import java.awt.Graphics;
import java.awt.Color;
abstract class Track {
// Increment each time a track is constructed
private protected static int nextId = 0;
// We need to talk to our container sometimes
static TrackCollection tc;
// Constants
static final int EMPTY = 999;
static final double SNAP_DIST = 6.0;
static final int NOT_GRIPPED = 0;
static final int TRANSLATE_MODE = 1;
static final int ROTATE_MODE_XY = 2;
static final int ROTATE_MODE_PQ = 3;
static final int GRIP_RANGE = 9;
static final int TIE_SIZE = 3;
int id; // id happens to == index in lines array
// state
int transformMode = NOT_GRIPPED;
boolean isGripped = false;
// Ties
Line ties[];
int tieCnt;
int connections[];
DblPoint connectionPoints[];
int connectionCnt;
private protected double x, y, ox, oy;
double cx, cy;
abstract void move(int argX, int argY);
abstract void rotate(double theta);
Track () {
id = nextId++;
}
void draw (Graphics g) {
int i;
for (i = 0; i < tieCnt; i++)
ties[i].draw(g);
for (i = 0; i < connectionCnt; i++) {
if (connections[i] != EMPTY)
g.setColor (Color.green);
else
g.setColor (Color.red);
g.drawOval (
(int)connectionPoints[i].x - 3,
(int)connectionPoints[i].y - 3,
6, 6);
}
}
boolean isConnectedTo (int id) {
for (int i = 0; i < connectionCnt; i++) {
if (connections[i] == id)
return true;
}
return false;
}
// Get track connected to this track which is
// NOT the same as the incoming track
int getNext (int id) {
for (int i = 0; i < connectionCnt; i++) {
if (connections[i] != EMPTY
&& connections[i] != id)
return connections[i];
}
return -1;
}
void instantiateObjects() {
ties = new Line[tieCnt];
connections = new int[connectionCnt];
connectionPoints = new DblPoint[connectionCnt];
for (int i = 0; i < tieCnt; i++)
ties[i] = new Line(new DblPoint(0,0),new DblPoint(0,0));
for (int i = 0; i < connectionCnt; i++) {
connections[i] = EMPTY;
connectionPoints[i] = new DblPoint (0, 0);
}
}
abstract void setMainLines();
abstract void setTies();
abstract void setConnectionPoints();
void restore () {
for (int i = 0; i < connectionCnt; i++)
connections[i] = Track.EMPTY;
}
int appendRunPoints (DblPoint pts[], int index, int id) {
if (connections[0] == id) {
for (int i = 0; i < tieCnt; i++) {
pts[index] = new DblPoint (ties[i].c);
index++;
}
pts[index] = new DblPoint (connectionPoints[1]);
index++;
}
else {
for (int i = tieCnt - 1; i > -1; i--) {
pts[index] = new DblPoint (
ties[i].c.x,
ties[i].c.y);
index++;
}
pts[index] = new DblPoint (connectionPoints[0]);
index++;
}
return index;
}
void rotate(int x, int y) {
DblPoint pivot;
DblPoint grip;
DblPoint mouse = new DblPoint ((double) x, ((double) y));
if (transformMode == ROTATE_MODE_XY) {
pivot = new DblPoint (connectionPoints[0]);
grip = new DblPoint (connectionPoints[1]);
}
else {
pivot = new DblPoint (connectionPoints[1]);
grip = new DblPoint (connectionPoints[0]);
}
// The y grows larger when moving down but I can't
// think that way. Make y increase as I move the
// mouse up
double thetaMouse = - (pivot.angleToPoint (mouse));
double thetaGrip = - (pivot.angleToPoint (grip));
if (thetaMouse >= thetaGrip) {
double thetaCCW = thetaMouse - thetaGrip; // counter-clockwise
if (thetaCCW <= Geometry.ONE_EIGHTY_DEGREES)
rotate (thetaCCW);
else
rotate (-1.0 * (Geometry.THREE_SIXTY_DEGREES - thetaCCW));
}
else {
double thetaCW = thetaMouse - thetaGrip;
if (thetaCW < -Geometry.ONE_EIGHTY_DEGREES)
rotate (thetaCW);
else
rotate (Geometry.THREE_SIXTY_DEGREES + thetaCW);
}
}
void releaseGrip () {
transformMode = NOT_GRIPPED;
}
void detach () {
for (int i = 0; i < connectionCnt; i++) {
if (connections[i] != EMPTY) {
tc.getTrack(connections[i]).detach(id);
connections[i] = EMPTY;
}
}
}
void detach (int otherId) {
// Only detach end which
// is connected to incoming guy
for (int i = 0; i < connectionCnt; i++) {
if (connections[i] == otherId)
connections[i] = EMPTY;
}
}
int tryToGrip (int x, int y, double distArg ) {
double distC;
double distXY;
double distPQ;
DblPoint xy = connectionPoints[0];
DblPoint pq = connectionPoints[1];
distC = Math.sqrt ((this.cx - (double) x) * (this.cx - (double) x)
+ (this.cy - y) * (this.cy - (double) y));
distXY = Math.sqrt ((xy.x - (double) x) * (xy.x - (double) x)
+ (xy.y - y) * (xy.y - (double) y));
distPQ = Math.sqrt ((pq.x - (double) x) * (pq.x - (double) x)
+ (pq.y - y) * (pq.y - (double) y));
// check if gripped in the middle
if (distC < GRIP_RANGE
|| distXY < GRIP_RANGE
|| distPQ < GRIP_RANGE) {
if (distC <= distXY && distC <= distPQ) {
transformMode = TRANSLATE_MODE;
distArg = distC;
}
else
if (distXY <= distC && distXY <= distPQ) {
transformMode = ROTATE_MODE_PQ;
distArg = distXY;
}
else {
transformMode = ROTATE_MODE_XY;
distArg = distPQ;
}
}
else {
transformMode = NOT_GRIPPED;
}
return transformMode;
}
void prepareForCircuitInquiry () {}
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// StraightTrack
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
class StraightTrack extends Track {
// Main line
Line ln;
StraightTrack (int x, int y) {
tieCnt = 3;
connectionCnt = 2;
instantiateObjects();
// save original position
ox = (double) x;
oy = (double) y;
restore ();
}
void setMainLines () {
ln = new Line(
new DblPoint(x, y),
new DblPoint(x + 40.0, y));
}
void setTies () {
double up = ln.c.y + TIE_SIZE;
double down = ln.c.y - TIE_SIZE;
double inc = 10.0;
ties[0].v1.x = x + inc;
ties[0].v1.y = up;
ties[0].v2.x = x + inc;
ties[0].v2.y = down;
ties[1].v1.x = ln.c.x;
ties[1].v1.y = up;
ties[1].v2.x = ln.c.x;
ties[1].v2.y = down;
ties[2].v1.x = x + (3 * inc);
ties[2].v1.y = up;
ties[2].v2.x = x + (3 * inc);
ties[2].v2.y = down;
}
void setConnectionPoints () {
connectionPoints[0].x = ln.v1.x;
connectionPoints[0].y = ln.v1.y;
connectionPoints[1].x = ln.v2.x;
connectionPoints[1].y = ln.v2.y;
cx = ln.c.x;
cy = ln.c.y;
}
void restore() {
x = ox;
y = oy;
super.restore();
setMainLines();
setTies();
setConnectionPoints();
}
void move(int argX, int argY) {
DblPoint vector = ln.moveTo (
(double) argX, (double) argY);
for (int i = 0; i < tieCnt; i++)
ties[i].translate(vector);
setConnectionPoints();
}
void rotate(double theta) {
DblPoint vector;
if (transformMode == ROTATE_MODE_XY)
vector = DblPoint.vector (Geometry.ORIGIN, ln.v1);
else if (transformMode == ROTATE_MODE_PQ)
vector = DblPoint.vector (Geometry.ORIGIN, ln.v2);
else
vector = DblPoint.vector (Geometry.ORIGIN, ln.c);
ln.rotate(vector, theta);
for (int i = 0; i < tieCnt; i++)
ties[i].rotate (vector, theta);
setConnectionPoints();
}
void draw (Graphics g) {
if (transformMode == NOT_GRIPPED)
g.setColor(Color.black);
else
g.setColor(Color.blue);
ln.draw (g);
super.draw(g);
}
} // end class StraightTrack
///////////////////////////////////////////////
///////////////////////////////////////////////
// CurvedTrack
///////////////////////////////////////////////
///////////////////////////////////////////////
// You must construct a piece of track as the upper
// right quadrant of a circle. After you construct
// it you can move it whereever you want
class CurvedTrack extends Track {
// Main line
Arc arc;
CurvedTrack (int x, int y)
{
tieCnt = 5;
connectionCnt = 2;
instantiateObjects();
ox = (double) x;
oy = (double) y;
restore ();
}
void setMainLines () {
arc = new Arc(new DblPoint(x,y+40), 40, 0.0, Geometry.NINETY_DEGREES);
}
void setTies () {
double centerX = arc.c.x;
double centerY = arc.c.y;
double theta;
DblPoint vector = DblPoint.vector (Geometry.ORIGIN, arc.c);
DblPoint pt = new DblPoint (0,0);
for (int i = 0; i < tieCnt; i++) {
ties[i].v1.x = centerX;
ties[i].v1.y = centerY + 3;
ties[i].v2.x = centerX;
ties[i].v2.y = centerY - 3;
theta = Geometry.degreesToRadians (-15.0 * (i + 1));
ties[i].rotate (vector, theta);
pt.x = Math.sin (-theta) * arc.radius;
pt.y = - Math.cos (theta) * arc.radius;
ties[i].translate (pt);
}
}
void setConnectionPoints () {
connectionPoints[0].x = arc.v1.x;
connectionPoints[0].y = arc.v1.y;
connectionPoints[1].x = arc.v2.x;
connectionPoints[1].y = arc.v2.y;
cx = arc.arcTo.x;
cy = arc.arcTo.y;
}
void restore() {
x = ox;
y = oy;
super.restore();
setMainLines();
setTies();
setConnectionPoints();
rotate(Geometry.FORTY_FIVE_DEGREES);
}
void move(int argX, int argY) {
DblPoint vector = arc.moveTo (
(double) argX, (double) argY);
for (int i = 0; i < tieCnt; i++)
ties[i].translate(vector);
setConnectionPoints();
}
void rotate(double theta) {
DblPoint vector;
if (transformMode == ROTATE_MODE_XY)
vector = DblPoint.vector (Geometry.ORIGIN, arc.v1);
else if (transformMode == ROTATE_MODE_PQ)
vector = DblPoint.vector (Geometry.ORIGIN, arc.v2);
else
vector = DblPoint.vector (Geometry.ORIGIN, arc.arcTo);
arc.rotate(vector, theta);
for (int i = 0; i < tieCnt; i++)
ties[i].rotate(vector, theta);
setConnectionPoints();
}
void draw (Graphics g) {
if (transformMode == NOT_GRIPPED)
g.setColor(Color.black);
else
g.setColor(Color.blue);
arc.draw (g);
super.draw(g);
}
}